package br.com.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import br.com.beans.Usuario;

/**
 * Classe de manipulacao de objetos persistidos via JPA
 * Objetos da classe bean Usuario
 */
public class UsuarioDAO extends GenericDAO<Usuario> {

	/**
	 * Valida um Usuario
	 * @param userName UserName do Usuario
	 * @param senha Senha do Usuario
	 * @return Objeto Usuario se bem sucedido ou null se houve erro.
	 */
	public Usuario validar(String userName, String senha) {
		EntityManager em = factory.createEntityManager();
		EntityTransaction t = em.getTransaction();
        Usuario usuario = null;

		try {
			t.begin();
			Query q = em.createQuery("from Usuario where userName = :userName and senha = :senha");
			q.setParameter("userName", userName);
			q.setParameter("senha", senha);
			usuario = (Usuario) q.getSingleResult();
			t.commit();

		} catch (Exception e) {
			if (debugInfo) {
				e.printStackTrace();
			}
			if (t.isActive()) t.rollback();

		} finally {
			em.close();
		}
		return usuario;
	}

	/**
	 * Altera a senha de um Usuario
	 * @param userName UserName do Usuario
	 * @param novaSenha Nova Senha do Usuario 
	 * @return True se bem sucedido, false se houve erro.
	 */
	public boolean alterarSenha(String userName, String novaSenha) {

		EntityManager em = factory.createEntityManager();
		EntityTransaction t = em.getTransaction();
		Usuario usuario = null;
		boolean resultado = false;

		
		try {

			if (novaSenha.length() < 6) throw new Exception("Senha muito curta.");

			t.begin();
			Query query = em.createQuery("from Usuario where userName like :userName");
			query.setParameter("userName", userName);
			usuario = (Usuario) query.getSingleResult();
			usuario.setSenha(novaSenha);

			em.merge(usuario);
			t.commit();
			resultado = true;

		} catch (Exception e) {

			if (debugInfo) {
				e.printStackTrace();
			}
			if (t.isActive()) t.rollback();

		} finally {

			em.close();
		}

		return resultado;
	}

	/**
	 * Exclui um Usuario persistido
	 * @param userName UserName do Usuario
	 * @return True se bem sucedido, false se houve erro.
	 */
	public boolean excluir(String userName) {

		EntityManager em = factory.createEntityManager();
		EntityTransaction t = em.getTransaction();
		Usuario obj = null;
		boolean result = false;

		try {

			t.begin();
			Query q = em.createQuery("from Usuario where userName = :userName");
			q.setParameter("userName", userName);
			obj = (Usuario) q.getSingleResult();
			em.remove(obj);
			t.commit();
			result = true;

		} catch (Exception e) {

			if (debugInfo) {
				e.printStackTrace();
			}
			if (t.isActive()) t.rollback();

		} finally {

			em.close();
		}
		
		return result;
	}

	/**
	 * Lista Usuarios por Nivel
	 * @param nivel Nivel do Usuario
	 * @return Lista de objetos persistidos
	 */
	@SuppressWarnings("unchecked")
	public List<Usuario> listar(Usuario.Nivel nivel) {

		EntityManager em = factory.createEntityManager();
		EntityTransaction t = em.getTransaction();
		List<Usuario> list = null;

		try {

			t.begin();
			Query q = em.createQuery("from Usuario where nivel = :nivel");
			q.setParameter("nivel", nivel);
			list = (List<Usuario>) q.getResultList();
			t.commit();

		} catch (Exception e) {

			if (debugInfo) {
				e.printStackTrace();
			}
			if (t.isActive()) t.rollback();

		} finally {

			em.close();
		}

		return list;
	}

	/**
	 * Localiza um usuario persistido pelo UserName
	 * @param userName UserName do usuario
	 * @return Objeto persistido
	 */
	public Usuario localizar(String userName) {

		EntityManager em = factory.createEntityManager();
		EntityTransaction t = em.getTransaction();
		Usuario obj = null;

		try {

			t.begin();
			Query query = em.createQuery("from Usuario where userName like :userName");
			query.setParameter("userName", userName);
			obj = (Usuario) query.getSingleResult();
			t.commit();

		} catch (Exception e) {

			if (debugInfo) {
				e.printStackTrace();
			}
			if (t.isActive()) t.rollback();

		} finally {

			em.close();
		}

		return obj;
	}
}
